"""
主窗口UI类
包含所有用户界面元素的创建和布局
"""

from PyQt5.QtWidgets import (QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, 
                             QGridLayout, QGroupBox, QCheckBox, QRadioButton, QComboBox, 
                             QLineEdit, QPushButton, QLabel, QFileDialog, QMessageBox, 
                             QButtonGroup)
from PyQt5.QtCore import Qt, pyqtSignal
import os
import config


class MainWindow(QMainWindow):
    """主窗口类，负责UI的创建和管理"""
    
    # 定义信号
    files_loaded = pyqtSignal(list)  # 文件加载完成信号
    plot_requested = pyqtSignal(dict)  # 绘图请求信号
    preview_requested = pyqtSignal()  # 预览请求信号
    
    def __init__(self):
        super().__init__()
        self.filepaths = []
        self.init_ui()
        
    def init_ui(self):
        """初始化用户界面"""
        self.setWindowTitle(config.APP_TITLE)
        self.setGeometry(*config.APP_GEOMETRY)
        
        # 主布局
        main_widget = QWidget()
        self.setCentralWidget(main_widget)
        main_layout = QHBoxLayout(main_widget)
        
        # 控制面板
        controls_panel = QWidget()
        controls_panel.setMaximumWidth(config.CONTROLS_PANEL_MAX_WIDTH)
        controls_panel_layout = QVBoxLayout(controls_panel)
        main_layout.addWidget(controls_panel)
        main_layout.addStretch()
        
        # 创建控制组件
        self.create_filename_group(controls_panel_layout)
        
        controls_layout = QGridLayout()
        self.create_channel_group(controls_layout)
        self.create_mode_group(controls_layout)
        self.create_stability_group(controls_layout)
        self.create_plot_style_group(controls_layout)
        self.create_command_group(controls_layout)
        controls_panel_layout.addLayout(controls_layout)
        
        self.create_parameter_group(controls_panel_layout)
        controls_panel_layout.addStretch(1)
        
        # 创建菜单栏
        self.create_menu_bar()
        
    def create_menu_bar(self):
        """创建菜单栏"""
        menubar = self.menuBar()
        file_menu = menubar.addMenu('&File')
        
        load_action = file_menu.addAction('&Load File(s)...')
        load_action.setShortcut(config.MENU_SHORTCUTS['load_files'])
        load_action.triggered.connect(self.load_files)
        
        file_menu.addSeparator()
        
        preview_action = file_menu.addAction('&Preview Data')
        preview_action.triggered.connect(self.preview_data)
        
        file_menu.addSeparator()
        
        exit_action = file_menu.addAction('&Exit')
        exit_action.setShortcut(config.MENU_SHORTCUTS['exit'])
        exit_action.triggered.connect(self.close)
        
        help_menu = menubar.addMenu('&Help')
        about_action = help_menu.addAction('&About')
        about_action.triggered.connect(
            lambda: QMessageBox.about(self, "About", config.APP_ABOUT_TEXT)
        )
        
    def create_filename_group(self, parent_layout):
        """创建文件名显示组"""
        group = QGroupBox("FILENAME")
        layout = QVBoxLayout()
        self.filename_display = QLineEdit(config.DEFAULT_FILENAME_DISPLAY)
        self.filename_display.setReadOnly(True)
        layout.addWidget(self.filename_display)
        group.setLayout(layout)
        parent_layout.addWidget(group)
        
    def create_channel_group(self, parent_layout):
        """创建通道选择组"""
        group = QGroupBox("SELECT CH.")
        layout = QGridLayout()
        
        self.channel_checkboxes = []
        self.channel_names = []
        
        for i in range(16):
            row, col = (i, 0) if i < 8 else (i - 8, 2)
            
            checkbox = QCheckBox(f"ADC{i+1}")
            self.channel_checkboxes.append(checkbox)
            layout.addWidget(checkbox, row, col)
            
            name_edit = QLineEdit(config.DEFAULT_CHANNEL_NAMES[i])
            self.channel_names.append(name_edit)
            layout.addWidget(name_edit, row, col + 1)
            
        group.setLayout(layout)
        parent_layout.addWidget(group, 0, 0)
        
    def create_mode_group(self, parent_layout):
        """创建模式选择组"""
        group = QGroupBox("SELECT MODE")
        layout = QGridLayout()
        
        self.plot_mode1_group = self._create_radio_group(["A/P", "I/Q"], layout, 0)
        self.plot_mode2_group = self._create_radio_group(["Wave", "FFT"], layout, 1)
        self.plot_mode3_group = self._create_radio_group(["Plot", "Save Figure"], layout, 2)
        self.plot_mode4_group = self._create_radio_group(["Auto", "Manual"], layout, 3, "Auto")
        self.plot_mode5_group = self._create_radio_group(
            [("Spon", "spurious_on_radio"), ("Spoff", "spurious_off_radio")], 
            layout, 4, "Spoff"
        )
        
        group.setLayout(layout)
        parent_layout.addWidget(group, 1, 0)
        
    def _create_radio_group(self, options, layout, row, default=None):
        """创建单选按钮组的辅助方法"""
        button_group = QButtonGroup(self)
        for i, option in enumerate(options):
            text, var_name = (option, None) if isinstance(option, str) else option
            radio = QRadioButton(text)
            if var_name:
                setattr(self, var_name, radio)
            button_group.addButton(radio)
            layout.addWidget(radio, row, i)
            if (default and text == default) or (not default and i == 0):
                radio.setChecked(True)
        return button_group
        
    def create_stability_group(self, parent_layout):
        """创建稳定性选择组"""
        group = QGroupBox("STABILITIES")
        layout = QHBoxLayout()
        self.da_check = QCheckBox("dA/A")
        self.dp_check = QCheckBox("dP")
        layout.addWidget(self.da_check)
        layout.addWidget(self.dp_check)
        group.setLayout(layout)
        parent_layout.addWidget(group, 2, 0)
        
    def create_plot_style_group(self, parent_layout):
        """创建绘图样式组"""
        group = QGroupBox("PLOT STYLE")
        layout = QGridLayout()
        
        # 字体大小、线宽、图形尺寸
        self.font_size_combo = self._add_combo(
            layout, "Font", 0, config.FONT_SIZE_OPTIONS, config.DEFAULT_FONT_SIZE
        )
        self.linewidth_combo = self._add_combo(
            layout, "Linewidth", 1, config.LINE_WIDTH_OPTIONS, config.DEFAULT_LINE_WIDTH
        )
        self.figsize_w_combo = self._add_combo(
            layout, "Figsize W", 2, config.FIGURE_WIDTH_OPTIONS, config.DEFAULT_FIGURE_WIDTH
        )
        self.figsize_h_combo = self._add_combo(
            layout, "Figsize H", 3, config.FIGURE_HEIGHT_OPTIONS, config.DEFAULT_FIGURE_HEIGHT
        )
        
        # 绘图样式（单个/多个，对数Y轴）
        self.plot_style_group = QButtonGroup(self)
        self.plot_style_single = QRadioButton("Single")
        self.plot_style_multi = QRadioButton("Multi")
        self.plot_style_single.setChecked(True)
        self.plot_style_group.addButton(self.plot_style_single)
        self.plot_style_group.addButton(self.plot_style_multi)
        layout.addWidget(self.plot_style_single, 4, 1)
        layout.addWidget(self.plot_style_multi, 4, 2)
        
        self.plot_style_logy = QCheckBox("LogY")
        layout.addWidget(self.plot_style_logy, 5, 1)
        
        group.setLayout(layout)
        parent_layout.addWidget(group, 0, 1)
        
    def _add_combo(self, layout, label, row, items, default):
        """添加下拉框的辅助方法"""
        layout.addWidget(QLabel(label), row, 0)
        combo = QComboBox()
        combo.addItems(items)
        combo.setCurrentText(default)
        layout.addWidget(combo, row, 1, 1, 2)
        return combo
        
    def create_command_group(self, parent_layout):
        """创建命令按钮组"""
        group = QGroupBox("COMMAND")
        layout = QHBoxLayout()
        plot_button = QPushButton("PLOT DATA")
        plot_button.clicked.connect(self.plot_data)
        layout.addWidget(plot_button)
        group.setLayout(layout)
        parent_layout.addWidget(group, 1, 1)
        
    def create_parameter_group(self, parent_layout):
        """创建参数设置组"""
        group = QGroupBox("UNIT AND TIME SCALE")
        layout = QGridLayout()
        
        self.fs_edit = self._add_param(layout, "Fs", 0, config.DEFAULT_SAMPLING_FREQ, "[MHz]")
        self.time_unit_combo = self._add_combo(layout, "Time Unit", 1, config.TIME_UNIT_OPTIONS, "[us]")
        self.t_start_edit = self._add_param(layout, "t_start", 2, config.DEFAULT_TIME_START)
        self.t_end_edit = self._add_param(layout, "t_end", 3, config.DEFAULT_TIME_END)
        self.freq_unit_combo = self._add_combo(layout, "Freq Unit", 4, config.FREQ_UNIT_OPTIONS, "[Hz]")
        self.f_start_edit = self._add_param(layout, "f_start", 5, config.DEFAULT_FREQ_START)
        self.f_end_edit = self._add_param(layout, "f_end", 6, config.DEFAULT_FREQ_END)
        self.p_min_edit = self._add_param(layout, "P_min", 7, "", "[deg]")
        self.p_max_edit = self._add_param(layout, "P_max", 8, "", "[deg]")
        self.sel_edit = self._add_param(layout, "SEL", 9, config.DEFAULT_SEL)
        self.beta_edit = self._add_param(layout, "BETA", 10, config.DEFAULT_BETA)
        
        group.setLayout(layout)
        parent_layout.addWidget(group)
        
    def _add_param(self, layout, label, row, default_val, unit=None):
        """添加参数输入框的辅助方法"""
        layout.addWidget(QLabel(label), row, 0)
        edit = QLineEdit(default_val)
        layout.addWidget(edit, row, 1)
        if unit:
            layout.addWidget(QLabel(unit), row, 2)
        return edit
        
    def load_files(self):
        """加载文件"""
        filenames, _ = QFileDialog.getOpenFileNames(
            self, "Select CSV Files", "", "CSV Files (*.csv);;All Files (*)"
        )
        if not filenames:
            return
            
        self.filepaths = filenames
        self.update_filename_display()
        self.files_loaded.emit(filenames)
        
    def update_filename_display(self):
        """更新文件名显示"""
        if not self.filepaths:
            self.filename_display.setText(config.DEFAULT_FILENAME_DISPLAY)
        else:
            fnames = [os.path.basename(f) for f in self.filepaths]
            self.filename_display.setText("; ".join(fnames))
            
    def preview_data(self):
        """预览数据"""
        if not self.filepaths:
            QMessageBox.warning(self, "Warning", "Please load a file first.")
            return
        self.preview_requested.emit()
        
    def plot_data(self):
        """绘制数据"""
        if not self.filepaths:
            QMessageBox.warning(self, "Warning", "Please load data file(s) first.")
            return
            
        # 收集所有UI参数
        parameters = self.get_plot_parameters()
        self.plot_requested.emit(parameters)
        
    def get_plot_parameters(self):
        """获取绘图参数"""
        channels_to_plot = [i for i, cb in enumerate(self.channel_checkboxes) if cb.isChecked()]
        if not channels_to_plot:
            channels_to_plot = [0]
            self.channel_checkboxes[0].setChecked(True)
            
        return {
            'filepaths': self.filepaths,
            'channels_to_plot': channels_to_plot,
            'plot_mode': self.plot_mode1_group.checkedButton().text(),
            'wave_or_fft': self.plot_mode2_group.checkedButton().text(),
            'plot_or_save': 'Save' if self.plot_mode3_group.checkedButton().text() == 'Save Figure' else 'Plot',
            'auto_manual': self.plot_mode4_group.checkedButton().text(),
            'spurious_mode': 'on' if self.spurious_on_radio.isChecked() else 'off',
            'single_multi': 'single' if self.plot_style_single.isChecked() else 'multi',
            'log_y': self.plot_style_logy.isChecked(),
            'da_stability': self.da_check.isChecked(),
            'dp_stability': self.dp_check.isChecked(),
            'font_size': int(self.font_size_combo.currentText()),
            'line_width': float(self.linewidth_combo.currentText()),
            'figure_size': (int(self.figsize_w_combo.currentText()), int(self.figsize_h_combo.currentText())),
            'time_unit': self.time_unit_combo.currentText(),
            'freq_unit': self.freq_unit_combo.currentText(),
            'channel_names': [name_edit.text() for name_edit in self.channel_names],
            'fs': self.fs_edit.text(),
            't_start': self.t_start_edit.text(),
            't_end': self.t_end_edit.text(),
            'f_start': self.f_start_edit.text(),
            'f_end': self.f_end_edit.text(),
            'p_min': self.p_min_edit.text(),
            'p_max': self.p_max_edit.text(),
            'sel': self.sel_edit.text(),
            'beta': self.beta_edit.text()
        }
        
    def set_fs_value(self, value):
        """设置采样频率值"""
        self.fs_edit.setText(str(value))
        
    def set_time_end_value(self, value):
        """设置时间结束值"""
        self.t_end_edit.setText(f"{value:.2f}")
        
    def show_preview_info(self, preview_text):
        """显示预览信息"""
        QMessageBox.information(self, "Data Preview", preview_text)
        
    def show_error_message(self, title, message):
        """显示错误消息"""
        QMessageBox.critical(self, title, message)
        
    def show_info_message(self, title, message):
        """显示信息消息"""
        QMessageBox.information(self, title, message)
        
    def show_warning_message(self, title, message):
        """显示警告消息"""
        QMessageBox.warning(self, title, message) 